// 新增权限、编辑权限
import React from 'react';
import { toJS } from 'mobx';
import { observer, useLocalStore } from 'mobx-react-lite';
import { useLocation, useHistory } from 'react-router';
import { parse } from 'qs';
import { Card, Form, Row, Col, Input, Button, Tree, message } from 'antd';
import * as addApi from '~/apis/permission/addApi';
import { genValidConfig, getExpandedKeys, generateList, loop, getAllChildList } from './pageConfig';
import './index.local.sass';

const FormItem = Form.Item;
const { Search } = Input;

const formItemLayout = {
  wrapperCol: { span: 20 },
};

const cardConfig = {
  size: 'small' as const,
  bordered: false,
};

// 搜索字典
const operationDictList = [] as any;
const dataDictList = [] as any;

const AddOrEditPermission = observer(() => {
  const location = useLocation();
  const history = useHistory();

  const querryParams = parse(location.search, { ignoreQueryPrefix: true });

  const state = useLocalStore(() => ({
    id: querryParams.id || '',
    loading: false,
    // 操作树
    operationTree: [] as any,
    expandedKeys: [] as any,
    searchValue: '',
    autoExpandParent: true,
    operationList: [] as any,
    // 数据树
    dataTree: [] as any,
    expandedDataKeys: [] as any,
    searchDataValue: '',
    autoExpandDataParent: true,
    dataList: [] as any,
  }));

  const [form] = Form.useForm();

  // 获取表单数据
  const getFormValus = () => form.validateFields().then((values: any) => {
    const params = {
      roleId: state.id,
      operateList: state.operationList,
      dataList: state.dataList,
      ...values,
    };

    return params;
  });

  const doSubmit = () => {
    getFormValus().then((params) => {
      state.loading = true;

      addApi.submitRole(params).then(() => {
        message.success('success');
      }).finally(() => {
        setTimeout(() => {
          state.loading = false;
        }, 2000);
      });
    }).catch(() => {
      message.error('validation error');
    });
  };

  const onSubmit = () => {
    doSubmit();
  };

  const onClose = () => {
    history.push('/permission/list');
  };

  // 表单填充
  const fillForm = (formData: any) => {
    const {
      name,
      operateList,
      dataList,
    } = formData;

    form.setFieldsValue({
      roleName: name,
    });

    state.operationList = operateList;
    state.expandedKeys = toJS(operateList);

    state.dataList = dataList;
    state.expandedDataKeys = toJS(dataList);
  };

  const getTreeData = () => {
    // 获取操作权限树
    addApi.getOperationTree().then((res) => {
      state.operationTree = res.data;

      // flat search tree
      generateList(res.data, operationDictList);
    });

    // 获取数据权限树
    addApi.getDataTree().then((res) => {
      state.dataTree = res.data;

      // flat search tree
      generateList(res.data, dataDictList);
    });
  };

  // initForm
  const initForm = () => {
    const params = {
      roleId: state.id,
    };

    addApi.getRolesDetail(params).then((res) => {
      fillForm(res.data);
    });
  };

  React.useEffect(() => {
    getTreeData();
    if (state.id) {
      initForm();
    }
  }, []);

  // 搜索成功时 展开树状图
  const onExpand = (expandedKeys: Array<any>) => {
    state.expandedKeys = expandedKeys;
    state.autoExpandParent = false;
  };

  const onDataExpand = (expandedKeys: Array<any>) => {
    state.expandedDataKeys = expandedKeys;
    state.autoExpandDataParent = false;
  };

  const onChange = (e: any) => {
    const { value } = e.target;

    state.expandedKeys = getExpandedKeys(value, state.operationTree, operationDictList);
    state.searchValue = value;
    state.autoExpandParent = true;
  };

  const onDataChange = (e: any) => {
    const { value } = e.target;

    state.expandedDataKeys = getExpandedKeys(value, state.dataTree, dataDictList);
    state.searchDataValue = value;
    state.autoExpandDataParent = true;
  };

  const onCheck = (checkedKeys: any, _info: any) => {
    state.operationList = checkedKeys.checked;
  };

  const onDataCheck = (checkedKeys: any, _info: any) => {
    state.dataList = checkedKeys.checked;
  };

  // 点击文本时切换 全选 / 全反选
  const onSelect = (selectKeys: any, info: any) => {
    const selectArr = getAllChildList(selectKeys[0], [info.node]);
    const selectStatus = info.selected;
    const curCheckList = toJS(state.operationList);
    const arrayDiff = curCheckList.filter((v: string) => !selectArr.includes(v));

    if (selectStatus) {
      // 全选当前节点与子节点
      state.operationList = arrayDiff.concat(selectArr);
    } else {
      // 取消选择
      state.operationList = arrayDiff;
    }

    state.expandedKeys = getExpandedKeys('', state.operationTree, operationDictList);
  };

  // 点击文本时切换 全选 / 全反选
  const onDataSelect = (selectKeys: any, info: any) => {
    const selectArr = getAllChildList(selectKeys[0], [info.node]);
    const selectStatus = !info.node.selected;
    const curCheckList = toJS(state.dataList);
    const arrayDiff = curCheckList.filter((v: string) => !selectArr.includes(v));

    if (selectStatus) {
      // 全选当前节点与子节点
      state.dataList = arrayDiff.concat(selectArr);
    } else {
      // 取消选择
      state.dataList = arrayDiff;
    }

    state.expandedDataKeys = getExpandedKeys('', state.dataTree, dataDictList);
  };

  const {
    loading,
    operationTree,
    dataTree,
    searchValue,
    expandedKeys,
    autoExpandParent,
    searchDataValue,
    expandedDataKeys,
    autoExpandDataParent,
    operationList,
    dataList,
  } = state;

  return (
    <div className="card-wrap">
      <Card
        className="card"
        {...cardConfig}
      >
        <Form form={form} layout="vertical" className="w-11/12">
          <Row>
            <Col span={12}>
              <FormItem
                name="roleName"
                label="Role name"
                rules={genValidConfig('Role name')}
                {...formItemLayout}
              >
                <Input
                  placeholder="Please input"
                  allowClear
                />
              </FormItem>
            </Col>
          </Row>

          <Row>
            <Col span={12}>
              <FormItem
                label="Operation permission settings"
                {...formItemLayout}
              >
                <Search
                  className="mb-2"
                  placeholder="Search"
                  value={searchValue}
                  onChange={onChange}
                />

                <div
                  className="mt-1 p-2 overflow-auto tree-wrap"
                >
                  {
                    // operation tree
                    operationTree.length
                      ? <Tree
                        checkable
                        selectable
                        checkStrictly
                        defaultExpandParent
                        checkedKeys={operationList}
                        onExpand={onExpand}
                        expandedKeys={expandedKeys}
                        autoExpandParent={autoExpandParent}
                        onCheck={onCheck}
                        onSelect={onSelect}
                        treeData={loop(operationTree, searchValue)}
                      />
                      : null
                  }
                </div>
              </FormItem>
            </Col>

            <Col span={12}>
              <FormItem
                label="Data access permission settings"
                {...formItemLayout}
              >
                <Search
                  className="mb-2"
                  placeholder="Search"
                  value={searchDataValue}
                  onChange={onDataChange}
                />

                <div
                  className="mt-1 p-2 overflow-auto tree-wrap"
                >
                  {
                    // data tree
                    dataTree.length
                      ? <Tree
                        checkable
                        selectable
                        checkStrictly
                        defaultExpandParent
                        checkedKeys={dataList}
                        onExpand={onDataExpand}
                        expandedKeys={expandedDataKeys}
                        autoExpandParent={autoExpandDataParent}
                        onCheck={onDataCheck}
                        onSelect={onDataSelect}
                        treeData={loop(dataTree, searchDataValue)}
                      />
                      : null
                  }
                </div>
              </FormItem>
            </Col>
          </Row>
        </Form>
      </Card>

      <div>
        <Button
          type="primary"
          className="mr-2"
          onClick={onSubmit}
          disabled={loading}
        >
          Submit
        </Button>

        <Button
          className="mr-2"
          onClick={onClose}
          disabled={loading}
        >
          Close
        </Button>
      </div>
    </div>
  );
});

export default AddOrEditPermission;
